#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "TGI.h"
#include "../TIN/TIN.h"
#include "../lib/Lsimple.h"
#include "../lib/Colas.h"
#include "../lib/Pilas.h"



void Espacios (char** linea, char* buscar, char* cambiar){
  char* linea2=(char*)malloc(sizeof(char)*(strlen(*linea)+1));
  char* linea3=(char*)malloc(sizeof(char)*(strlen(*linea)+1));
  int i;

  for (i=0;i<strlen(*linea);i++){
    linea2[i+1]='\0';
    linea2[i]=(*linea)[i];
    if (strstr(linea2,buscar)!=NULL){
      strncpy(linea3,linea2,i);
      linea3[i]='\0';
      strcat(linea3,cambiar);
      strcpy(linea2,linea3);
    }
  }
    strcpy(*linea,linea2);
    free(linea2);
    free(linea3);
}

int leer_string(FILE* archivo, char** linea){
  int error;
  char* linea2=NULL;
  linea2=(char*)malloc(sizeof(char)*1000);
  if (feof(archivo)){
    free(linea2);
    return -2;
  }
  error=fscanf(archivo,"%s",(linea2));
  if (error!=TRUE){
    free(linea2);
    return -2;
  }
  if (!strcmp(linea2,_EOL)){
    return -1;
  }
  *linea=(char*)malloc(sizeof(char)*(strlen(linea2)+1));
  strcpy(*linea,linea2);
  Espacios (linea, _ESPACIO, " ");
  free(linea2);
  return 0;
}

int leer_int(FILE* archivo){
  int error,dato;
  char* linea=(char*)malloc(sizeof(char)*1000);
  if (feof(archivo)){
    free(linea);
    return -2;
  }
  error=fscanf(archivo,"%s",(linea));
  if (error!=TRUE){
    free(linea);
    return -2;
  }
    if (!strcmp(linea,_EOL)){
      free(linea);
      return -1;
    }
  if (!strcmp(linea,"")) return -2;
  if (linea!=NULL) dato= atoi(linea); else dato=0;
  free(linea);
  return dato;
}

void Crear_prioridades (TListaSimple* prioridades){
  TCola incidencias;
  C_Crear(&incidencias, sizeof(TIN));
  LS_Crear(prioridades, sizeof(TListaSimple));
  LS_Insertar(prioridades, LS_PRIMERO, &incidencias);
  LS_Insertar(prioridades, LS_SIGUIENTE, &incidencias);
  LS_Insertar(prioridades, LS_SIGUIENTE, &incidencias);
  LS_Insertar(prioridades, LS_SIGUIENTE, &incidencias);
  LS_Insertar(prioridades, LS_SIGUIENTE, &incidencias);
}

void Liberar_prioridades (TListaSimple* prioridades){
  TCola incidencias;
  LS_MoverCte(prioridades,LS_PRIMERO);
  while (!LS_Vacia(*prioridades)){
    LS_ObtenerCte(*prioridades,&incidencias);
    if (!C_Vacia(incidencias))
      C_Vaciar(&incidencias);
    LS_BorrarCte(prioridades);
  }
}

 int Cargar_Usuarios(TGI* tgi, const char* usuarios){
  FILE* fusuarios;
	TListaSimple AUXusuarios;
  user_t usuario;
	int error,numero;
  if (!(fusuarios=fopen(usuarios,"r"))) return -1;

  AUXusuarios=tgi->usuarios;
  LS_Crear(&(AUXusuarios), sizeof(user_t));
  while ((!feof(fusuarios))||(numero!=-2)){
    numero=leer_int(fusuarios);
    if (numero!=-2){
      usuario.user_id=numero;
      leer_string(fusuarios, &(usuario.user_name));
      Crear_prioridades (&(usuario.prioridades));
      if(LS_Vacia(AUXusuarios))
        LS_Insertar(&(AUXusuarios), LS_PRIMERO, &usuario);
      else
        LS_Insertar(&(AUXusuarios), LS_SIGUIENTE, &usuario);
      //free(usuario.user_name);
      error=0;
      while ((error!=-1)&&(error!=-2))
        error=leer_int(fusuarios);
    }
  }

  tgi->usuarios=AUXusuarios;
  fclose (fusuarios);
  return 0;
}

int Cargar_Proyectos(TGI* tgi, const char* proyectos){
  FILE* fproyectos;
	TListaSimple AUXproyectos;
  project_t proyecto;
	int error,numero;
  if (!(fproyectos=fopen(proyectos,"r"))) return -1;

  AUXproyectos=tgi->proyectos;
  LS_Crear(&(AUXproyectos), sizeof(project_t));
  while ((!feof(fproyectos))||(numero!=-2)){
    numero=leer_int(fproyectos);
    if (numero!=-2){
      proyecto.project_id=numero;
      leer_string(fproyectos, &(proyecto.project_name));
      Crear_prioridades (&(proyecto.prioridades));
      if(LS_Vacia(AUXproyectos))
        LS_Insertar(&(AUXproyectos), LS_PRIMERO, &proyecto);
      else
        LS_Insertar(&(AUXproyectos), LS_SIGUIENTE, &proyecto);
      //free(proyecto.project_name);
      error=0;
      while ((error!=-1)&&(error!=-2))
        error=leer_int(fproyectos);
    }
  }

  tgi->proyectos=AUXproyectos;
  fclose (fproyectos);
  return 0;
}

void incidencia_usuario(TListaSimple* usuarios, int id, const prior_inci_t p, TIN* tin){
  int i,error,encontrado=FALSE;
  user_t usuario;
  TCola incidencia_usuario;

//Busco usuario>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  error=LS_MoverCte(usuarios, LS_PRIMERO);
  while ((error)&&(!encontrado)){
    LS_ObtenerCte(*usuarios, &usuario);
    if (usuario.user_id==id)
      encontrado=TRUE;
    else
      error=LS_MoverCte(usuarios,LS_SIGUIENTE);
  }
//Busco usuario<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//Busco prioridad>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  LS_MoverCte(&(usuario.prioridades),LS_PRIMERO);
  for (i=0;i<p+1;i++)
    LS_MoverCte(&(usuario.prioridades),LS_SIGUIENTE);
  LS_ObtenerCte(usuario.prioridades, &incidencia_usuario);
//Busco prioridad<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  C_Agregar(&incidencia_usuario, tin);
  LS_ModificarCte (&(usuario.prioridades), &incidencia_usuario);
}

void incidencia_proyecto(TListaSimple* proyectos, int id, prior_inci_t p, TIN* tin){
  int i;
  int error,encontrado=FALSE;
  project_t proyecto;
  TCola incidencia_proyect;

//Busco proyecto>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  error=LS_MoverCte(proyectos,LS_PRIMERO);
  while ((error)&&(!encontrado)){
    LS_ObtenerCte(*proyectos, &proyecto);
    if (proyecto.project_id==id)
      encontrado=TRUE;
    else
      error=LS_MoverCte(proyectos,LS_SIGUIENTE);
  }
//Busco proyecto<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

//Busco prioridad>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  LS_MoverCte(&(proyecto.prioridades),LS_PRIMERO);
  for (i=0;i<p+1;i++)
    LS_MoverCte(&(proyecto.prioridades),LS_SIGUIENTE);
  LS_ObtenerCte(proyecto.prioridades, &incidencia_proyect);
//Busco prioridad<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  C_Agregar(&incidencia_proyect, tin);
  LS_ModificarCte (&(proyecto.prioridades), &incidencia_proyect);
}

int Cargar_Incidencias (TGI* tgi, const char* incidencias){
  FILE* fincidencias;
  TIN tin;
 	TListaSimple AUXusuarios;
 	TListaSimple AUXproyectos;
 	TListaSimple AUXincidencias;
 	int continuar;
//Campos de TIN>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  int inci_id;
	tipo_inci_t inci_type;
	prior_inci_t inci_priority;
	int inci_user;
	int inci_assigned_user;
	int inci_project_id;
	resol_inci_t inci_resolved;
  inci_comment_t comentarios;
  inci_status_t estados;
	char* inci_date_created;
	char* inci_summary;
	char* inci_description;
	char* inci_date_solved;
  char* stat_desc;
//Campos de TIN<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

  if (!(fincidencias=fopen(incidencias,"r"))) return -1;
  AUXusuarios=tgi->usuarios;
  AUXproyectos=tgi->proyectos;
  AUXincidencias=tgi->incidencias;
  LS_Crear(&(AUXincidencias), sizeof(tin));

  while (!feof(fincidencias)){
    inci_id=leer_int(fincidencias);
    if (inci_id!=-2){
      inci_type=leer_int(fincidencias);
      inci_priority=leer_int(fincidencias);
      inci_user=leer_int(fincidencias);
      inci_assigned_user=leer_int(fincidencias);
      leer_string(fincidencias, &inci_date_created);
      inci_project_id=leer_int(fincidencias);
      leer_string(fincidencias, &inci_summary);
      leer_string(fincidencias, &inci_description);
      TIN_Crear (&tin, inci_id, inci_type, inci_priority, inci_user, inci_assigned_user, inci_date_created, inci_project_id, inci_summary, inci_description);
      continuar=0;
      while (!continuar){
        leer_string(fincidencias, &(estados.stat_date));
        if (strcmp(estados.stat_date,_SEP)){
          estados.stat_user_id=leer_int(fincidencias);
          leer_string(fincidencias, &(stat_desc));
          TIN_CambiarEstado(&tin, estados.stat_date, estados.stat_user_id, stat_desc);
          free(estados.stat_date);
          free(stat_desc);
        }else{
          continuar++;
          free(estados.stat_date);
        }
      }
      continuar=0;
      while (!continuar){
        leer_string(fincidencias, &(comentarios.comm_date));
        if (strcmp(comentarios.comm_date,_SEP)){
          comentarios.comm_user_id=leer_int(fincidencias);
          leer_string(fincidencias, &(comentarios.comm_desc));
          TIN_Comentar(&tin, comentarios.comm_date, comentarios.comm_user_id, comentarios.comm_desc);
          free(comentarios.comm_date);
          free(comentarios.comm_desc);
        }else{
          continuar++;
          free(comentarios.comm_date);
        }
      }
      leer_string(fincidencias, &(inci_date_solved));
      inci_resolved=leer_int(fincidencias);
      TIN_Resolver(&tin, inci_date_solved, inci_user, inci_resolved);
      while (leer_int(fincidencias)!=-1);
      //Cargar incidencias en TGI>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      if (LS_Vacia(AUXincidencias))
        LS_Insertar(&(AUXincidencias),LS_PRIMERO, &tin);
      else
        LS_Insertar(&(AUXincidencias),LS_SIGUIENTE, &tin);
      incidencia_usuario(&AUXusuarios, inci_user, inci_priority, &tin);
      incidencia_proyecto(&AUXproyectos, inci_project_id, inci_priority, &tin);
      //Cargar incidencias en TGI<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
      free(inci_date_created);
      free(inci_summary);
      free(inci_description);
      free(inci_date_solved);
    }
  }
  fclose(fincidencias);
  tgi->usuarios=AUXusuarios;
  tgi->proyectos=AUXproyectos;
  tgi->incidencias=AUXincidencias;
  return 0;
}

void grabar_tin (TIN tin){
  FILE* fincidencias=fopen("incidencias.txt","a");
  int inci_id;
	tipo_inci_t inci_type;
	prior_inci_t inci_priority;
	int inci_user;
	int inci_assigned_user;
	int inci_project_id;
	resol_inci_t inci_resolved;
	char* inci_date_created;
	char* inci_summary;
	char* inci_description;
	char* cod_estado;
	char* inci_date_solved;
  inci_comment_t comentarios;
  inci_status_t estados;
  TListaSimple lcomentarios;
  TListaSimple lestados;
  LS_Crear(&lcomentarios,sizeof(comentarios));
  LS_Crear(&lestados,sizeof(estados));

  TIN_GetDatos ( &tin, &inci_id, &inci_type, &inci_priority, &inci_user, &inci_assigned_user, &inci_date_created, &inci_project_id, &inci_summary, &inci_description);
  Espacios (&inci_date_created, " ", _ESPACIO);
  Espacios (&inci_summary, " ", _ESPACIO);
  Espacios (&inci_description, " ", _ESPACIO);
  fprintf(fincidencias,"%d %d %d %d %d %s %d %s %s ",inci_id, inci_type, inci_priority, inci_user, inci_assigned_user, inci_date_created, inci_project_id, inci_summary, inci_description);

  TIN_GetListaEstados( &tin, &lestados);
  LS_MoverCte (&(lestados), LS_PRIMERO);
  while (!LS_Vacia(lestados)){
    LS_ObtenerCte (lestados, &estados);
    LS_BorrarCte (&(lestados));
    if (estados.stat_desc==0){
      cod_estado=(char*)malloc(sizeof(char)*(strlen("TIN_OPEN")+1));
      strcpy (cod_estado,"TIN_OPEN");
    }
    if (estados.stat_desc==1){
      cod_estado=(char*)malloc(sizeof(char)*(strlen("TIN_PROGRESS")+1));
      strcpy (cod_estado,"TIN_PROGRESS");
    }
    if (estados.stat_desc==2){
      cod_estado=(char*)malloc(sizeof(char)*(strlen("TIN_RESOLVED")+1));
      strcpy (cod_estado,"TIN_RESOLVED");
    }
    if (estados.stat_desc==3){
      cod_estado=(char*)malloc(sizeof(char)*(strlen("TIN_REOPEN")+1));
      strcpy (cod_estado,"TIN_REOPEN");
    }
    if (estados.stat_desc==4){
      cod_estado=(char*)malloc(sizeof(char)*(strlen("TIN_CLOSED")+1));
      strcpy (cod_estado,"TIN_CLOSED");
    }
  Espacios (&estados.stat_date, " ", _ESPACIO);

    fprintf(fincidencias,"%s %d %s ",estados.stat_date,estados.stat_user_id,cod_estado);
    free(cod_estado);
    free(estados.stat_date);
  }
  fprintf(fincidencias,"%s ",_SEP);

  TIN_GetListaComentarios( &tin,&lcomentarios );
  LS_MoverCte (&(lcomentarios), LS_PRIMERO);
  while (!LS_Vacia(lcomentarios)){
    LS_ObtenerCte (lcomentarios, &comentarios);
    LS_BorrarCte (&(lcomentarios));
    Espacios (&comentarios.comm_date, " ", _ESPACIO);
    Espacios (&comentarios.comm_desc, " ", _ESPACIO);
    fprintf(fincidencias,"%s %d %s ",comentarios.comm_date, comentarios.comm_user_id,comentarios.comm_desc);
    free(comentarios.comm_date);
    free(comentarios.comm_desc);
  }
  fprintf(fincidencias,"%s ",_SEP);

  Get_resolucion(tin, &inci_resolved, &inci_date_solved);
  Espacios (&inci_date_solved, " ", _ESPACIO);
  fprintf(fincidencias,"%s %d %s\n",tin.inci_date_solved, tin.inci_resolved,_EOL);

  fclose(fincidencias);
	free(inci_date_created);
	free(inci_summary);
	free(inci_description);
  free(inci_date_solved);
  if(!LS_Vacia(lcomentarios)) LS_Vaciar(&(lcomentarios));
  if(!LS_Vacia(lestados)) LS_Vaciar(&(lestados));
}

int buscar_usuario(TListaSimple usuarios,int id){
  int error;
  user_t usuario;
  error=LS_MoverCte(&usuarios, LS_PRIMERO);
  error=(!LS_Vacia(usuarios));
  while (error){
    LS_ObtenerCte(usuarios, &usuario);
    if (usuario.user_id==id)
      return TRUE;
    else
      error=LS_MoverCte(&usuarios,LS_SIGUIENTE);
  }
  return FALSE;
}

int buscar_usuario_nombre(TListaSimple lusuarios,const char* nombre){
  int error;
  user_t usuario;
  if(LS_Vacia(lusuarios)) return -1;
  error=LS_MoverCte(&lusuarios, LS_PRIMERO);
  while (error){
    LS_ObtenerCte(lusuarios, &usuario);
    if (!strcmp(usuario.user_name,nombre))
      return TRUE;
    else
      error=LS_MoverCte(&lusuarios,LS_SIGUIENTE);
  }
  return FALSE;
}

int buscar_proyecto(TListaSimple proyectos, int id){
  int error;
  project_t proyecto;
  error=LS_MoverCte(&proyectos, LS_PRIMERO);
  error=(!LS_Vacia(proyectos));
  while (error){
    LS_ObtenerCte(proyectos, &proyecto);
    if (proyecto.project_id==id)
      return TRUE;
    else
      error=LS_MoverCte(&proyectos,LS_SIGUIENTE);
  }
  return FALSE;
}

int buscar_proyecto_nombre(TListaSimple proyectos, const char* nombre){
  int error;
  project_t proyecto;
  if(LS_Vacia(proyectos)) return -1;
  error=LS_MoverCte(&proyectos, LS_PRIMERO);
  while (error){
    LS_ObtenerCte(proyectos, &proyecto);
    if (!strcmp(proyecto.project_name,nombre))
      return TRUE;
    else
      error=LS_MoverCte(&proyectos,LS_SIGUIENTE);
  }
  return FALSE;
}

int Agregar_Usuario (TGI* tgi, const char* usuarios, const char* nombre){
  TListaSimple AUXusuarios=tgi->usuarios;
  FILE* fusuarios;
  int error,id;
  user_t usuario;

  if (!(fusuarios=fopen(usuarios,"a"))) return -1;
  if ((buscar_usuario_nombre(tgi->usuarios,nombre)==FALSE)||((buscar_usuario_nombre(tgi->usuarios,nombre)==-1))){
    if (LS_Vacia(AUXusuarios)){
      id=1;
    }else{
    error=LS_MoverCte(&AUXusuarios,LS_PRIMERO);
    while (error){
      error=LS_MoverCte(&AUXusuarios,LS_SIGUIENTE);
    }
    LS_ObtenerCte(AUXusuarios,&usuario);
    id=usuario.user_id+1;
    }
    fprintf(fusuarios,"%d %s %s\n",id,nombre,_EOL);
  }else{
    fprintf(stderr,"Ya existe el usuario \n");
    fclose(fusuarios);
    return -1;
  }


  fclose(fusuarios);
  return 0;
}

int Agregar_Proyecto (TGI* tgi, const char* proyectos, const char* nombre){
  TListaSimple AUXproyectos=tgi->proyectos;
  FILE* fproyectos;
  int error,id;
  project_t proyecto;

  if (!(fproyectos=fopen(proyectos,"a"))) return -1;
  if ((buscar_proyecto_nombre(AUXproyectos,nombre)==FALSE)||(buscar_proyecto_nombre(AUXproyectos,nombre)==-1)){

    if (LS_Vacia(AUXproyectos)){
      id=1;
    }else{
    error=LS_MoverCte(&AUXproyectos,LS_PRIMERO);
    while (error){
      error=LS_MoverCte(&AUXproyectos,LS_SIGUIENTE);
    }
    LS_ObtenerCte(AUXproyectos,&proyecto);
    id=proyecto.project_id+1;
    }
    fprintf(fproyectos,"%d %s %s\n",id,nombre,_EOL);
  }else{
    fprintf(stderr,"Ya existe el proyecto \n");
    fclose(fproyectos);
    return -1;
  }
  fclose(fproyectos);
  return 0;
}





int TGI_Crear ( TGI* tgi, const char* proyectos, const char* usuarios, const char* incidencias){
  Cargar_Proyectos(tgi,proyectos);
  Cargar_Usuarios(tgi,usuarios);
  Cargar_Incidencias (tgi, incidencias);
  return 0;
}


int TGI_Cerrar( TGI* tgi){
  user_t usuario;
	project_t proyecto;
	TListaSimple AUXusuarios;
	TListaSimple AUXproyectos;
	TListaSimple AUXincidencias;
  AUXusuarios=tgi->usuarios;
  AUXproyectos=tgi->proyectos;
  AUXincidencias=tgi->incidencias;
  TIN tin;
  FILE* fincidencias=fopen("incidencias.txt","wt");
  fclose(fincidencias);  //Se abre y se cierra para borra todo su contenido.

  LS_MoverCte(&AUXusuarios,LS_PRIMERO);
  while (!LS_Vacia(AUXusuarios)){
    LS_ObtenerCte(AUXusuarios,&usuario);
    free(usuario.user_name);
    Liberar_prioridades(&(usuario.prioridades));
    LS_BorrarCte(&AUXusuarios);
  }
  LS_MoverCte(&AUXproyectos,LS_PRIMERO);
  while (!LS_Vacia(AUXproyectos)){
    LS_ObtenerCte(AUXproyectos,&proyecto);
    free(proyecto.project_name);
    Liberar_prioridades(&(proyecto.prioridades));
    LS_BorrarCte(&AUXproyectos);
  }
  LS_MoverCte(&AUXincidencias,LS_PRIMERO);
  while (!LS_Vacia(AUXincidencias)){
    LS_ObtenerCte(AUXincidencias,&tin);
    grabar_tin (tin);
    TIN_Liberar(&tin);
    LS_BorrarCte(&AUXincidencias);
  }

  tgi->usuarios=AUXusuarios;
  tgi->proyectos=AUXproyectos;
  tgi->incidencias=AUXincidencias;
  return 0;
}


int TGI_AgregarIncidencia ( TGI* tgi, tipo_inci_t inci_type, prior_inci_t inci_priority,int inci_user, int inci_assigned_user, char* inci_date_created, int inci_project_id, char*	inci_summary, char* inci_description){
  int estado;
  TIN tin;
  int inci_id;
	tipo_inci_t inci_type2;
	prior_inci_t inci_priority2;
	int inci_user2;
	int inci_assigned_user2;
	int inci_project_id2;
	char* inci_date_created2;
	char* inci_summary2;
	char* inci_description2;
  TListaSimple AUXusuarios;
  TListaSimple AUXproyectos;
  TListaSimple AUXincidencias;
  AUXusuarios=tgi->usuarios;
  AUXproyectos=tgi->proyectos;
  AUXincidencias=tgi->incidencias;

  if (!(buscar_usuario(AUXusuarios,inci_user))) return -2;
  if (!(buscar_proyecto(AUXproyectos,inci_project_id))) return -1;
  if (!(buscar_usuario(AUXusuarios,inci_assigned_user))) return -3;

  estado=LS_Vacia(AUXincidencias);
  if (estado)
    inci_id=1;
  else{
    LS_MoverCte(&AUXincidencias, LS_PRIMERO);
    while (!(AUXincidencias.Cte->Sig==NULL))
      LS_MoverCte(&AUXincidencias,LS_SIGUIENTE);
    LS_ObtenerCte (AUXincidencias, &tin);
    TIN_GetDatos ( &tin, &inci_id, &inci_type2, &inci_priority2, &inci_user2, &inci_assigned_user2, &inci_date_created2, &inci_project_id2, &inci_summary2, &inci_description2);
    inci_id++;
  }
  if (TIN_Crear (&tin, inci_id, inci_type, inci_priority, inci_user, inci_assigned_user, inci_date_created, inci_project_id, inci_summary, inci_description)!=0) return -3;
  if (TIN_Resolver(&tin, inci_date_created, inci_user, TIN_DONT_FIX)) return -3;
  if (TIN_Comentar(&tin, inci_date_created, inci_user, "Se genera una nueva incidencia.")) return -3;
  if (TIN_CambiarEstado( &tin, inci_date_created, inci_user, "TIN_OPEN")) return -3;

  if (LS_Vacia(AUXincidencias))
    LS_Insertar(&AUXincidencias,LS_PRIMERO, &tin);
  else
    LS_Insertar(&AUXincidencias,LS_SIGUIENTE, &tin);
  incidencia_usuario(&AUXusuarios, inci_user, inci_priority, &tin);
  incidencia_proyecto(&AUXproyectos, inci_project_id, inci_priority, &tin);

  if (!estado){
    free(inci_date_created2);
    free(inci_summary2);
    free(inci_description2);
  }
  tgi->incidencias=AUXincidencias;
  tgi->proyectos=AUXproyectos;
  tgi->usuarios=AUXusuarios;
  return 0;
}


int TGI_GetIncidencia( const TGI* tgi, int inci, TIN* tin){
  TIN tin2;
  int inci_id;
	tipo_inci_t inci_type2;
	prior_inci_t inci_priority2;
	int inci_user2;
	int inci_assigned_user2;
	int inci_project_id2;
	char* inci_date_created2;
	char* inci_summary2;
	char* inci_description2;
  TListaSimple AUXincidencias;
  AUXincidencias=tgi->incidencias;

  int encontrado=FALSE;
  int error;

  error=LS_MoverCte(&AUXincidencias, LS_PRIMERO);
  error=(!LS_Vacia(AUXincidencias));
  while ((error)&&(!encontrado)){
    LS_ObtenerCte(AUXincidencias, &tin2);
    TIN_GetDatos ( &tin2, &inci_id, &inci_type2, &inci_priority2, &inci_user2, &inci_assigned_user2, &inci_date_created2, &inci_project_id2, &inci_summary2, &inci_description2);
    if (inci_id==inci)
      encontrado=TRUE;
    else
      error=LS_MoverCte(&AUXincidencias,LS_SIGUIENTE);
    free(inci_date_created2);
    free(inci_summary2);
    free(inci_description2);
  }
  if (encontrado){
    LS_ObtenerCte (AUXincidencias, tin);
    return 0;
  }else
    return -1;
}


int TGI_GetIncidenciasUsuario( const TGI* tgi, int usuario, TCola* incidencias){
  TIN tin;
  int i;
  int error,encontrado=FALSE;
  int code;
  user_t usuario2;
  TCola incidencias_usuario;
  TCola AUXcola;
  TListaSimple AUXusuarios;
  AUXusuarios=tgi->usuarios;
  C_Crear (incidencias,sizeof(TIN));
  C_Crear (&AUXcola,sizeof(TIN));

//Busco usuario>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  error=LS_MoverCte(&AUXusuarios,LS_PRIMERO);
  error=(!LS_Vacia(AUXusuarios));
  while ((error)&&(!encontrado)){
    LS_ObtenerCte(AUXusuarios, &usuario2);
    if (usuario2.user_id==usuario)
      encontrado=TRUE;
    else
      error=LS_MoverCte(&AUXusuarios,LS_SIGUIENTE);
  }
//Busco usuario<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  if (encontrado==FALSE) return -2;

  LS_MoverCte(&(usuario2.prioridades),LS_PRIMERO);
  for (i=0;i<TIN_TRIVIAL+1;i++){
    LS_ObtenerCte(usuario2.prioridades, &incidencias_usuario);
    if (!C_Vacia(AUXcola))
      C_Vaciar(&AUXcola);
    while (!C_Vacia(incidencias_usuario)){
      code=C_Sacar(&incidencias_usuario, &tin);
      if (code){
        C_Agregar(&AUXcola, &tin);
        C_Agregar(incidencias, &tin);
      }
    }
    LS_ModificarCte(&(usuario2.prioridades),&incidencias_usuario);
    while (!C_Vacia(AUXcola)){
      code=C_Sacar(&AUXcola, &tin);
      if (code){
        incidencia_usuario(&AUXusuarios, tin.inci_id, tin.inci_priority,&tin);
      }
    }
    LS_MoverCte(&(usuario2.prioridades),LS_SIGUIENTE);
  }
  if (C_Vacia(*incidencias)) return -1;
  return 0;
}


int TGI_GetIncidenciasProyecto( const TGI* tgi, int proyecto, TListaSimple* incidencias){
  TIN tin;
  int i;
  int error,encontrado=FALSE;
  int code;
  project_t proyecto2;
  TCola incidencias_usuario;
  TListaSimple AUXproyectos;
  TCola AUXcola;

  AUXproyectos=tgi->proyectos;
  LS_Crear (incidencias,sizeof(tin));
  C_Crear (&AUXcola,sizeof(TIN));

//Busco proyecto>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  error=LS_MoverCte(&AUXproyectos,LS_PRIMERO);
  error=(!LS_Vacia(AUXproyectos));
  while ((error)&&(!encontrado)){
    LS_ObtenerCte(AUXproyectos, &proyecto2);
    if (proyecto2.project_id==proyecto)
      encontrado=TRUE;
    else
      error=LS_MoverCte(&AUXproyectos,LS_SIGUIENTE);
  }
//Busco proyecto<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  if (encontrado==FALSE) return -2;

  LS_MoverCte(&(proyecto2.prioridades),LS_PRIMERO);
  for (i=0;i<TIN_TRIVIAL+1;i++){
    LS_ObtenerCte(proyecto2.prioridades, &incidencias_usuario);
    if (!C_Vacia(AUXcola))
      C_Vaciar(&AUXcola);
    while (!C_Vacia(incidencias_usuario)){
      code=C_Sacar(&incidencias_usuario, &tin);
      if (code){
        C_Agregar(&AUXcola, &tin);
        LS_Insertar (incidencias, LS_SIGUIENTE, &tin);
      }
    }
    LS_ModificarCte(&(proyecto2.prioridades),&incidencias_usuario);
    while (!C_Vacia(AUXcola)){
      code=C_Sacar(&AUXcola, &tin);
      if (code){
       incidencia_proyecto(&AUXproyectos, tin.inci_id, tin.inci_priority,&tin);
      }
    }
    LS_MoverCte(&(proyecto2.prioridades),LS_SIGUIENTE);
  }
  if (LS_Vacia(*incidencias)) return -1;
  return 0;
}


int TGI_Borrar_Incidencia (TGI* tgi, int inci){
  TIN tin;
  int inci_id;
	tipo_inci_t inci_type2;
	prior_inci_t inci_priority2;
	int inci_user2;
	int inci_assigned_user2;
	int inci_project_id2;
	char* inci_date_created2;
	char* inci_summary2;
	char* inci_description2;
  TListaSimple AUXincidencias;
  AUXincidencias=tgi->incidencias;

  int encontrado=FALSE;
  int error;

  error=LS_MoverCte(&AUXincidencias, LS_PRIMERO);
  error=(!LS_Vacia(AUXincidencias));
  while ((error)&&(!encontrado)){
    LS_ObtenerCte(AUXincidencias, &tin);
    TIN_GetDatos ( &tin, &inci_id, &inci_type2, &inci_priority2, &inci_user2, &inci_assigned_user2, &inci_date_created2, &inci_project_id2, &inci_summary2, &inci_description2);
    if (inci_id==inci)
      encontrado=TRUE;
    else
      error=LS_MoverCte(&AUXincidencias,LS_SIGUIENTE);
    free(inci_date_created2);
    free(inci_summary2);
    free(inci_description2);
  }
  if (encontrado==FALSE) return -1;
  TIN_Liberar(&tin);
  LS_BorrarCte(&AUXincidencias);
  return 0;
}


int TGI_Modificar_Incidencia (TGI* tgi, TIN* tin){
  TIN tin2;
  int inci_id2;
	tipo_inci_t inci_type2;
	prior_inci_t inci_priority2;
	int inci_user2;
	int inci_assigned_user2;
	int inci_project_id2;
	char* inci_date_created2;
	char* inci_summary2;
	char* inci_description2;

  int inci_id;
	tipo_inci_t inci_type;
	prior_inci_t inci_priority;
	int inci_user;
	int inci_assigned_user;
	int inci_project_id;
	char* inci_date_created;
	char* inci_summary;
	char* inci_description;

  TIN_GetDatos ( tin, &inci_id, &inci_type, &inci_priority, &inci_user, &inci_assigned_user, &inci_date_created, &inci_project_id, &inci_summary, &inci_description);
  free(inci_date_created);
  free(inci_summary);
  free(inci_description);

  TListaSimple AUXincidencias;
  AUXincidencias=tgi->incidencias;

  int encontrado=FALSE;
  int error;

  error=LS_MoverCte(&AUXincidencias, LS_PRIMERO);
  error=(!LS_Vacia(AUXincidencias));
  while ((error)&&(!encontrado)){
    LS_ObtenerCte(AUXincidencias, &tin2);
    TIN_GetDatos ( &tin2, &inci_id2, &inci_type2, &inci_priority2, &inci_user2, &inci_assigned_user2, &inci_date_created2, &inci_project_id2, &inci_summary2, &inci_description2);
    if (inci_id==inci_id2)
      encontrado=TRUE;
    else
      error=LS_MoverCte(&AUXincidencias,LS_SIGUIENTE);
    free(inci_date_created2);
    free(inci_summary2);
    free(inci_description2);
  }
  if (encontrado==FALSE) return -1;
  LS_ModificarCte(&AUXincidencias,tin);
  return 0;
}
